Skip to content

feat(aws): expand SES/STS/Secrets Manager tool coverage, fix API alignment gaps#5450

Merged
waleedlatif1 merged 6 commits into
stagingfrom
validate/aws-ses-sts-secretsmanager
Jul 7, 2026
Merged

feat(aws): expand SES/STS/Secrets Manager tool coverage, fix API alignment gaps#5450
waleedlatif1 merged 6 commits into
stagingfrom
validate/aws-ses-sts-secretsmanager

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Ran a full /validate-integration audit on the SES, STS, and Secrets Manager integrations against live AWS API docs
  • Closed all high-value coverage gaps found: 10 new SES tools (suppression list management, email identity CRUD, template update, configuration set creation, custom verification email), 2 new STS tools (AssumeRoleWithWebIdentity, AssumeRoleWithSAML) plus session-tag/policy-ARN support on assume_role, 5 new Secrets Manager tools (describe_secret, tag_resource, untag_resource, restore_secret, rotate_secret)
  • Fixed a real defect in secrets_manager_list_secrets that silently dropped rotation/version metadata the block's own bundled templates relied on
  • A second independent validation pass caught two SES bugs before shipping: create_configuration_set was silently dropping httpsPolicy when no customRedirectDomain was set (now validated with a clear 400), and list_suppressed_destinations wasn't validating the reasons filter against AWS's BOUNCE/COMPLAINT enum (now rejects invalid values instead of surfacing a generic 500)
  • Normalized tool versions to 1.0.0 and alphabetized the Secrets Manager registry section
  • All 31 tools (original + new) verified param-by-param and field-by-field against live AWS API docs; confirmed fully backwards compatible — no existing param, response field, or tool ID was renamed or removed

Type of Change

  • New feature (tool coverage expansion)
  • Bug fix (SES config-set/suppression validation gaps, Secrets Manager list_secrets missing fields)

Testing

  • Two independent rounds of live-AWS-doc validation via parallel subagents, plus manual re-verification of the two bugs found in round two
  • bunx tsc --noEmit, bun run lint, bun run check:api-validation all pass

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…nment gaps

- SES: add suppression list management, email identity CRUD, template
  update, configuration set creation, custom verification email (10
  new tools); fix silent httpsPolicy drop in create_configuration_set
  and unvalidated suppression reason enum in list_suppressed_destinations
- STS: add AssumeRoleWithWebIdentity and AssumeRoleWithSAML (unsigned,
  no static credentials required); extend assume_role with
  policyArns/tags/transitiveTagKeys session params
- Secrets Manager: add describe_secret, tag_resource, untag_resource,
  restore_secret, rotate_secret; fix list_secrets dropping
  rotation/version metadata fields; normalize tool versions to 1.0.0
  and alphabetize registry entries

All 31 tools verified param-by-param against live AWS API docs across
two independent audit passes.
@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 7, 2026 12:03am

Request Review

@cursor

cursor Bot commented Jul 6, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Large expansion of security-sensitive surfaces (secret rotation, STS federation returning temporary credentials, SES identity/suppression changes) with high blast radius if misconfigured, though routes still use internal auth and existing patterns.

Overview
Expands AWS Secrets Manager, SES v2, and STS workflow integrations with many new operations, matching docs/registry updates, while keeping existing tool IDs and params backward compatible.

Secrets Manager adds describe (metadata without values), tag/untag, restore from scheduled delete, and rotate (schedule/Lambda options). List secrets now returns rotation rules, version-to-stage maps, and related dates that were previously dropped.

SES adds template update, account suppression list management, email identity create/get/delete, configuration set creation, and custom verification email sends, with block UI fields and outputs wired for each.

STS adds Assume Role With Web Identity and Assume Role With SAML (no static IAM keys on those paths via a placeholder-credentials client), and extends assume role with managed policy ARNs, session tags, and transitive tag keys.

Validation fixes: SES create configuration set requires customRedirectDomain when httpsPolicy is set; list suppressed destinations rejects invalid suppression reasons with 400 instead of a generic 500.

Reviewed by Cursor Bugbot for commit 6656103. Configure here.

Comment thread apps/sim/app/api/tools/ses/create-configuration-set/route.ts
Comment thread apps/sim/lib/api/contracts/tools/aws/secrets-manager-rotate-secret.ts Outdated
Comment thread apps/sim/lib/api/contracts/tools/aws/ses-create-configuration-set.ts Outdated
Comment thread apps/sim/lib/api/contracts/tools/aws/ses-create-email-identity.ts Outdated
@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR expands AWS tool coverage across SES, STS, and Secrets Manager by adding 17 new tools and fixing two real defects: list_secrets was silently omitting rotation/version metadata that its own bundled templates relied on, and list_suppressed_destinations was not guarding its reasons filter against the BOUNCE/COMPLAINT enum.

  • SES gains 10 new tools (suppression list CRUD, email identity CRUD, template update, configuration set creation, custom verification email) with contract-level validation for suppressedReasons and the httpsPolicy/customRedirectDomain dependency enforced via superRefine.
  • STS adds AssumeRoleWithWebIdentity and AssumeRoleWithSAML using a dedicated createUnauthenticatedSTSClient that supplies placeholder credentials to skip the default credential provider chain; the approach is valid since AWS does not verify the request signature for these two operations.
  • Secrets Manager adds describe_secret, tag_resource, untag_resource, restore_secret, and rotate_secret, with the rotate contract correctly enforcing mutual exclusivity of automaticallyAfterDays and scheduleExpression.

Confidence Score: 5/5

Safe to merge — all 17 new tools follow established route/contract/utils patterns, the two fixed defects are correctly addressed, and no existing tool IDs or response fields were removed or renamed.

Each new route validates inputs through a typed Zod contract before any AWS SDK call is made, sensitive tokens (SAML assertions, web identity tokens) are never logged, and the unauthenticated STS client pattern is technically sound for the two operations that AWS permits without a signed request. The list_secrets metadata fix and the suppression-reason enum guards are straightforward and correct.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/api/tools/sts/utils.ts Adds createUnauthenticatedSTSClient with well-commented placeholder credentials for federation operations, plus parseTags/parsePolicyArns/parseTransitiveTagKeys helpers and new assumeRoleWithWebIdentity/assumeRoleWithSAML implementations; all guarded by contract-level validation upstream.
apps/sim/app/api/tools/ses/utils.ts Adds updateTemplate, suppression list CRUD, createEmailIdentity, deleteEmailIdentity, getEmailIdentity, createConfigurationSet, and sendCustomVerificationEmail; logic correctly mirrors AWS SDK parameter shapes and conditionally omits optional fields.
apps/sim/app/api/tools/secrets_manager/utils.ts Adds describeSecret, tagResource, untagResource, restoreSecret, rotateSecret functions and fixes listSecrets to include rotation/version metadata.
apps/sim/app/api/tools/ses/create-configuration-set/route.ts New route; suppressedReasons validated by contract refine (BOUNCE/COMPLAINT only) and httpsPolicy/customRedirectDomain dependency enforced via superRefine.
apps/sim/app/api/tools/ses/list-suppressed-destinations/route.ts New route that validates reasons against BOUNCE/COMPLAINT enum at the route level, returning a clear 400 for invalid values.
apps/sim/lib/api/contracts/tools/aws/sts-assume-role.ts Adds policyArns, tags (JSON-validated), and transitiveTagKeys fields with appropriate refine validators.
apps/sim/lib/api/contracts/tools/aws/secrets-manager-rotate-secret.ts Correctly enforces mutually exclusive automaticallyAfterDays/scheduleExpression via superRefine and validates duration format.
apps/sim/app/api/tools/sts/assume-role-with-saml/route.ts New route for AssumeRoleWithSAML; SAML assertion never logged, no credential leakage in error paths.
apps/sim/lib/api/contracts/tools/aws/ses-create-configuration-set.ts Validates suppressedReasons as BOUNCE/COMPLAINT-only and enforces customRedirectDomain required when httpsPolicy is set.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client as Sim Client
    participant Route as Route Handler
    participant Contract as Zod Contract
    participant Utils as AWS Utils
    participant AWS as AWS Service

    Client->>Route: POST assume-role-with-web-identity
    Route->>Route: checkInternalAuth()
    Route->>Contract: parseToolRequest()
    Contract-->>Route: validated params or 400
    Route->>Utils: createUnauthenticatedSTSClient(region)
    Note over Utils: placeholder credentials to bypass default chain
    Route->>Utils: assumeRoleWithWebIdentity(...)
    Utils->>AWS: AssumeRoleWithWebIdentityCommand
    Note over AWS: signature not verified by AWS for this op
    AWS-->>Utils: Credentials + metadata
    Utils-->>Route: accessKeyId, sessionToken, expiration
    Route-->>Client: 200 JSON

    Client->>Route: POST create-configuration-set
    Route->>Contract: parseToolRequest()
    Note over Contract: superRefine enforces httpsPolicy needs customRedirectDomain
    Contract-->>Route: validated params or 400
    Route->>Utils: createConfigurationSet(...)
    Utils->>AWS: CreateConfigurationSetCommand
    AWS-->>Utils: success
    Route-->>Client: 200 JSON
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client as Sim Client
    participant Route as Route Handler
    participant Contract as Zod Contract
    participant Utils as AWS Utils
    participant AWS as AWS Service

    Client->>Route: POST assume-role-with-web-identity
    Route->>Route: checkInternalAuth()
    Route->>Contract: parseToolRequest()
    Contract-->>Route: validated params or 400
    Route->>Utils: createUnauthenticatedSTSClient(region)
    Note over Utils: placeholder credentials to bypass default chain
    Route->>Utils: assumeRoleWithWebIdentity(...)
    Utils->>AWS: AssumeRoleWithWebIdentityCommand
    Note over AWS: signature not verified by AWS for this op
    AWS-->>Utils: Credentials + metadata
    Utils-->>Route: accessKeyId, sessionToken, expiration
    Route-->>Client: 200 JSON

    Client->>Route: POST create-configuration-set
    Route->>Contract: parseToolRequest()
    Note over Contract: superRefine enforces httpsPolicy needs customRedirectDomain
    Contract-->>Route: validated params or 400
    Route->>Utils: createConfigurationSet(...)
    Utils->>AWS: CreateConfigurationSetCommand
    AWS-->>Utils: success
    Route-->>Client: 200 JSON
Loading

Reviews (7): Last reviewed commit: "fix(sts): supply placeholder credentials..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/ses/create-configuration-set/route.ts
Comment thread apps/sim/app/api/tools/ses/create-email-identity/route.ts Outdated
Comment thread apps/sim/app/api/tools/sts/utils.ts
…Manager rotation

- ses_create_configuration_set: validate suppressedReasons against
  BOUNCE/COMPLAINT enum before calling AWS (was silently reaching AWS
  as a generic 500 for bad values); tags now a proper Zod array schema
  instead of a string with route-side JSON.parse
- ses_create_email_identity: dkimSigningAttributes and tags now proper
  Zod object/array schemas instead of strings with route-side
  JSON.parse, matching the pattern used elsewhere (e.g. sts_assume_role
  tags, secrets_manager_tag_resource)
- secrets_manager_rotate_secret: reject automaticallyAfterDays and
  scheduleExpression when both are supplied — AWS RotationRules
  accepts only one
- sts createUnauthenticatedSTSClient: corrected a misleading comment
  claiming these calls are fully unsigned; the SDK still falls through
  its default credential provider chain
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/ses.ts Outdated
The SES block declared the tags and dkimSigningAttributes block inputs
as 'string' instead of 'json', so the generic block executor never
parsed the JSON code-editor value before forwarding it — workflow runs
sent a raw JSON string where the contract now expects a structured
object/array, failing validation. Also corrected the corresponding
tool param TypeScript types, which were still typed as string | null.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/ses.ts Outdated
…guration_set

Boolean('false') evaluates to true, so turning off the
reputationMetricsEnabled or sendingEnabled switch sent the opposite of
the user's choice to SES. Match the established === 'true' string
comparison pattern used elsewhere in the codebase.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/blocks/blocks/sts.ts Outdated
tags was declared as a 'json' block input, so the generic executor
JSON.parse'd it before the switch-case handler ran — but that handler
already converts the raw table-rows array (or a passthrough string)
into the JSON string the sts_assume_role contract expects. Declaring
it 'json' broke that conversion for non-string inputs. Reverted to
'string' so the handler's existing string/array disambiguation runs
on the untouched raw value.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/tools/sts/utils.ts
createUnauthenticatedSTSClient omitted credentials entirely, so the
SDK's signing middleware fell through the default credential provider
chain and threw CredentialsProviderError before the request was sent
in any environment with no ambient AWS identity — even though
AssumeRoleWithWebIdentity/AssumeRoleWithSAML never check the
signature. Static placeholder credentials skip that resolution
without granting or requiring any real IAM identity.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1 waleedlatif1 merged commit fb3f95d into staging Jul 7, 2026
18 checks passed
@waleedlatif1 waleedlatif1 deleted the validate/aws-ses-sts-secretsmanager branch July 7, 2026 00:26
Comment thread apps/sim/app/api/tools/sts/utils.ts
Comment thread apps/sim/app/api/tools/ses/list-suppressed-destinations/route.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile please re-review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 6656103. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant